package components;

import java.util.LinkedList;

public class InputNeuron extends AbstractNeuron {

	private LinkedList<Double> spkTimes = new LinkedList<Double>();
	
	public InputNeuron(int index) {
		super(true, index);
	}

	@Override
	public boolean update(double timeStep) {
		if(spkTimes != null && !spkTimes.isEmpty()){
			try{
				if(spkTimes.peek() <= time){	
					spkTimes.poll();
					spike();
					time += timeStep;
					return true;
				} else {
					time += timeStep;
					return false;
				}
			}catch(NullPointerException e){
				if(spkTimes.peek() == null) {
					System.out.println("First element is null");
					System.out.println(spkTimes.size());
					System.out.println(spkTimes.peekLast());
				} else {
					System.out.println(spkTimes.peek());
				}
				e.printStackTrace();
				System.exit(1);
			}
		}
		return false;
	}

	@Override
	protected void spike() {
	setLastSpike(getTime()); //Set now as last time we spiked
		
		if(isReporter()) {
			getRecorder().spikeEvent(getIndex());
		}
		//ItepreferredISI over efferent synapses...
		for (int i = 0, n = getFanOut().size(); i < n; i++) {
			getFanOut().get(i).charge(getTime());
		}		
		
		if(isStdpOn()) {
			/* Only apply to fan out, since by definition input neurons have no
			 * fan in.*/
			getStdp().applySTDPRule(getFanOut(), getTime(), false);
		}
	}

	public void addSpkTime(double spkTime) {
		if(!spkTimes.isEmpty() && spkTimes.getLast() > spkTime) {
			System.out.println(spkTime);
			System.out.println(spkTimes.getLast());
			throw new IllegalArgumentException("Spike Times were not" +
					" entered in chronological order.");
		} else {
			spkTimes.add(spkTime);
		}
	}
	
	public Double peekLast(){
		if(!spkTimes.isEmpty()){
			return spkTimes.peekLast();
		} else {
			return 0.0;
		}
	}

}
